{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Copyright 2014 Brett Slatkin, Pearson Education Inc.\n",
    "#\n",
    "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "#     http://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License.\n",
    "\n",
    "# Preamble to mimick book environment\n",
    "import logging\n",
    "from pprint import pprint\n",
    "from sys import stdout as STDOUT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Example 1\n",
    "handle = open('random_data.txt', 'w', encoding='utf-8')\n",
    "handle.write('success\\nand\\nnew\\nlines')\n",
    "handle.close()\n",
    "handle = open('random_data.txt')  # May raise IOError\n",
    "try:\n",
    "    data = handle.read()  # May raise UnicodeDecodeError\n",
    "finally:\n",
    "    handle.close()        # Always runs after try:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### try\tblock\tdoesn’t\traise\tan\texception, the\telse\tblock\twill\trun. Use this nice 'else'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Example 2\n",
    "import json\n",
    "\n",
    "def load_json_key(data, key):\n",
    "    try:\n",
    "        result_dict = json.loads(data)  # May raise ValueError\n",
    "    except ValueError as e:\n",
    "        raise KeyError from e\n",
    "    else:\n",
    "        return result_dict[key]         # May raise KeyError\n",
    "\n",
    "# JSON decode successful\n",
    "assert load_json_key('{\"foo\": \"bar\"}', 'foo') == 'bar'\n",
    "try:\n",
    "    load_json_key('{\"foo\": \"bar\"}', 'does not exist')\n",
    "    assert False\n",
    "except KeyError:\n",
    "    pass  # Expected\n",
    "\n",
    "# JSON decode fails\n",
    "try:\n",
    "    load_json_key('{\"foo\": bad payload', 'foo')\n",
    "    assert False\n",
    "except KeyError:\n",
    "    pass  # Expected"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Example 3\n",
    "import json\n",
    "UNDEFINED = object()\n",
    "\n",
    "def divide_json(path):\n",
    "    handle = open(path, 'r+')   # May raise IOError\n",
    "    try:\n",
    "        data = handle.read()    # May raise UnicodeDecodeError\n",
    "        op = json.loads(data)   # May raise ValueError\n",
    "        value = (\n",
    "            op['numerator'] /\n",
    "            op['denominator'])  # May raise ZeroDivisionError\n",
    "    except ZeroDivisionError as e:\n",
    "        return UNDEFINED\n",
    "    else:\n",
    "        op['result'] = value\n",
    "        result = json.dumps(op)\n",
    "        handle.seek(0)\n",
    "        handle.write(result)    # May raise IOError\n",
    "        return value\n",
    "    finally:\n",
    "        handle.close()          # Always runs\n",
    "\n",
    "# Everything works\n",
    "temp_path = 'random_data.json'\n",
    "handle = open(temp_path, 'w')\n",
    "handle.write('{\"numerator\": 1, \"denominator\": 10}')\n",
    "handle.close()\n",
    "assert divide_json(temp_path) == 0.1\n",
    "\n",
    "# Divide by Zero error\n",
    "handle = open(temp_path, 'w')\n",
    "handle.write('{\"numerator\": 1, \"denominator\": 0}')\n",
    "handle.close()\n",
    "assert divide_json(temp_path) is UNDEFINED\n",
    "\n",
    "# JSON decode error\n",
    "handle = open(temp_path, 'w')\n",
    "handle.write('{\"numerator\": 1 bad data')\n",
    "handle.close()\n",
    "try:\n",
    "    divide_json(temp_path)\n",
    "    assert False\n",
    "except ValueError:\n",
    "    pass  # Expected"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
